
# coding=utf-8

from paho.mqtt import client as mqttc

class Connect:

    def __init__(self, paraDict: dict, client_id):

        self._broker = paraDict["ip"]
        self._port = paraDict["port"]
        self._topic = paraDict["topic"]
        self._client_id = client_id
        self._username = paraDict["username"]
        self._password = paraDict["password"]

        # self._client = self._connect_mqtt()
        self._client = None
        while self._client is None:
            try:
                self._client = self._connect_mqtt()
            except Exception as e:
                print(e)
                print(self._client)
                pass


    def loopStart(self):
        self._client.loop_start()


    def loopForever(self):
        self._client.loop_forever()


    def _connect_mqtt(self):
        def on_connect(client, userdata, flags, rc):
            if rc == 0:
                print("Connected to MQTT Broker!")
            else:
                print("Failed to connect, return code %d\n", rc)

        client = mqttc.Client(self._client_id, transport="tcp")
        client.username_pw_set(self._username, password=self._password)
        client.on_connect = on_connect

        client.connect(self._broker, self._port)

        return client



class Sender(Connect):

    def __init__(self, paraDict: dict, client_id):
        super().__init__(paraDict, client_id)


    def send(self, msg, retain=False):
        # print('retain:', retain)
        # msgStr = str(msg.dict)
        msgStr = msg
        msgStr = msgStr.replace("\'", "\"")

        result = self._client.publish(self._topic, msgStr, retain=retain)
        # result: [0, 1]
        status = result[0]
        if status == 0:
            print(u"Send `{}` to topic `{}`".format(msgStr, self._topic))
            pass
        else:
            print(u"Failed to send message to topic {}".format(self._topic))



class Receiver(Connect):

    def __init__(self, paraDict: dict, client_id):
        super().__init__(paraDict, client_id)


    def startReceiveLoop(self, on_message=None):
        if on_message is None:
            def on_message(client, userdata, msg):
                # print(type(msg))
                # msg_data = msg.payload.decode('unicode_escape')
                msg_data = msg.payload.decode('utf-8')
                # print(u"received `{}` from `{}` topic".format(msg_data, msg.topic))

        self._client.subscribe(self._topic)
        self._client.on_message = on_message
        self._client.loop_forever()